package com.xjrh.traintravel.collector.netty.handler;

import com.xjrh.common.core.utils.ObjectUtils;
import com.xjrh.traintravel.collector.common.CodeConvertor;
import com.xjrh.traintravel.collector.common.NettyGlobalException;
import com.xjrh.traintravel.collector.common.StringUtil;
import com.xjrh.traintravel.collector.netty.coder.Encoder;
import com.xjrh.traintravel.collector.netty.coder.command.AgreementStructure;
import com.xjrh.traintravel.collector.runner.NettyClientManager;
import io.netty.util.AttributeKey;
import org.springframework.stereotype.Component;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;
import javax.annotation.Resource;

/**
 * 基础指令处理类
 *
 * @author snps
 * @create 2022-03-02 8:38
 * @describe
 **/
@Component
@Slf4j
public class BaseAgreementHandler {

    /**
     * 给channel增加的属性，用于做唯一的"连接标识"
     *      channel.attribute.key-equipmentId
     */
    public static final String ATTR_KEY_EQUIPMENT_ID = "equipmentId";

    @Resource
    private NettyClientManager nettyClientManager;


    /**
     * 从客户端连接中获取 设备标识
     * @param channel 客户端连接
     * @return 设备标识
     */
     public String getClientChannelKey(Channel channel) {
        AttributeKey<String> attrEquipmentId = AttributeKey.valueOf(BaseAgreementHandler.ATTR_KEY_EQUIPMENT_ID);
        if (channel.hasAttr(attrEquipmentId)) {
            return channel.attr(attrEquipmentId).get();
        } else {
            return StringUtil.STRING_EMPTY;
        }
    }

    /**
     * 通过设备标识，获取客户端连接
     * @param equipmentId 设备标识
     * @return Channel 客户端连接
     */
    public Channel getClientChannel(String equipmentId) {
         return nettyClientManager.getClientChannel(equipmentId);
    }

    /**
     * 移除客户端连接
     *
     * @param channelId 客户端连接Id
     */
    public void removeClientChannel(String channelId) {
        nettyClientManager.removeClientChannel(channelId);
    }


    /**
     * 发送命令
     *
     * @param agreement 通讯协议
     * @param channel 连接通道
     */
    public void sendCommand(AgreementStructure agreement, Channel channel) {
        if (agreement == null) {
            throw new NettyGlobalException("通讯协议，为空！");
        }
        if (channel == null) {
            throw new NettyGlobalException("连接通道，为空！");
        }

        // 命令转16进制
        String hexCommand = Encoder.encode(agreement);
        // log.warn("发送指令：{}", hexCommand);

        // 发送命令
        try {
            ByteBuf buff = Unpooled.buffer();
            buff.writeBytes(CodeConvertor.hexString2Bytes(hexCommand));
            channel.writeAndFlush(buff);
        } catch (Exception ex) {
            // ex.printStackTrace();
            throw new NettyGlobalException("发送命令异常！").setDetailMessage(ex.getMessage());
        }
    }

    /**
     * 发送命令
     *
     * @param agreement 通讯协议
     */
    public void sendCommand(AgreementStructure agreement) {
        if (agreement == null) {
            throw new NettyGlobalException("通讯协议，为空！");
        }
        if (StringUtil.isEmpty(agreement.getAddr())) {
            throw new NettyGlobalException("通讯协议-MAC地址，为空！");
        }

        // 获取客户端连接
        Channel channel = nettyClientManager.getClientChannel(agreement.getAddr());
        /*if (channel == null) {
            throw new NettyGlobalException("连接通道【" + agreement.getAddr() + "】，为空！");
        }*/

        // 命令转16进制
        String hexCommand = Encoder.encode(agreement);
        // log.warn("发送指令：{}", hexCommand);

        // 发送命令
        try {
            ByteBuf buff = Unpooled.buffer();
            buff.writeBytes(CodeConvertor.hexString2Bytes(hexCommand));
            channel.writeAndFlush(buff);
        } catch (Exception ex) {
            // ex.printStackTrace();
            throw new NettyGlobalException("发送命令异常！").setDetailMessage(ex.getMessage());
        }
    }

    /**
     * 发送命令
     *
     * @param hexCommand 16进制命令
     * @param channel 连接通道
     */
    public void sendCommand(String hexCommand, Channel channel) {
        if (StringUtil.isEmpty(hexCommand)) {
            throw new NettyGlobalException("16进制命令，为空！");
        }
        if (channel == null) {
            throw new NettyGlobalException("连接通道，为空！");
        }

        // 发送命令
        try {
            ByteBuf buff = Unpooled.buffer();
            buff.writeBytes(CodeConvertor.hexString2Bytes(hexCommand));
            channel.writeAndFlush(buff);
        } catch (Exception ex) {
            // ex.printStackTrace();
            throw new NettyGlobalException("发送命令异常！").setDetailMessage(ex.getMessage());
        }
    }

    /**
     * 获取：客户端连接-车序号
     * @param clientChannelId 客户端连接标识（设备ID）
     * @return String 车序号
     */
    protected String getEquipmentSeq(String clientChannelId) {
        Integer equipmentSeq = nettyClientManager.getClientChannelSeq(clientChannelId);
        if (ObjectUtils.isNull(equipmentSeq)) {
            return "00";
        }
        return CodeConvertor.intToHexString(equipmentSeq, 1);
    }

}